wayland: Handle subsurface as popup parent
authorJonas Ådahl <jadahl@gmail.com>
Thu, 5 Jan 2017 08:01:49 +0000 (16:01 +0800)
committerOlivier Fourdan <ofourdan@redhat.com>
Tue, 17 Jan 2017 08:02:41 +0000 (09:02 +0100)
When a subsurface is used as a parent of a popup, GDK needs to traverse
up to the transient-for as the next parent, to properly find the parent
used by the popup positioner. This is because the parent of a popup
must always either be an xdg_popup or an xdg_surface, but traversing
the "parent" (in GDK terms) upwards from a subsurface will end up on
the fake root window before we hit the actual parent (in Wayland terms).

https://bugzilla.gnome.org/show_bug.cgi?id=776225

gdk/wayland/gdkwindow-wayland.c

index 2348d4123a630504708057a12539e11405ee637d..674dac5b68c717770c3ab5d940cc8af752beec5a 100644 (file)
@@ -1641,13 +1641,25 @@ get_real_parent_and_translate (GdkWindow *window,
   GdkWindowImplWayland *impl = GDK_WINDOW_IMPL_WAYLAND (window->impl);
   GdkWindow *parent = impl->transient_for;
 
-  while (parent &&
-         !gdk_window_has_native (parent) &&
-         gdk_window_get_parent (parent))
+  while (parent)
     {
+      GdkWindowImplWayland *parent_impl =
+        GDK_WINDOW_IMPL_WAYLAND (parent->impl);
+      GdkWindow *effective_parent = gdk_window_get_parent (parent);
+
+      if ((gdk_window_has_native (parent) &&
+           !parent_impl->display_server.wl_subsurface) ||
+          !effective_parent)
+        break;
+
       *x += parent->x;
       *y += parent->y;
-      parent = gdk_window_get_parent (parent);
+
+      if (gdk_window_has_native (parent) &&
+          parent_impl->display_server.wl_subsurface)
+        parent = parent->transient_for;
+      else
+        parent = effective_parent;
     }
 
   return parent;